import { CustomModel } from '../types';

const defaultParamMapping = new Map<string, string>(
  [
    ['W', 'W'],
    ['D', 'D'],
    ['H', 'H'],
    ['CZ', 'materialBrandGoodId'],
    [null, 'ButtCode'],
    [null, 'OName'],
    [null, 'MJPP'],
    [null, 'MJLX'],
    [null, 'ANFTQ'],
    [null, 'MJSL'],
    [null, 'MJ1'],
    [null, 'MJ2'],
    [null, 'MJ3'],
    [null, 'MJ4'],
    [null, 'MJ5'],
    [null, 'MJ6'],
    [null, 'LZQ'],
    [null, 'LZQWZ'],
    [null, 'KCJBZ'],
    [null, 'LAQKCW'],
    [null, 'LZQKCD'],
    [null, 'YMMX'],
    [null, 'YWLS'],
    [null, 'LSLDGD'],
    ['fit', 'fit'],
    ['KMFX', 'openDirection'],
    ['BSWZ', 'handlePosition'],
    ['BSFX', 'handleRotate'],
    ['YG', 'coverType'],
    ['SYG', 'uCoverType'],
    ['XYG', 'dCoverType'],
    ['ZYG', 'lCoverType'],
    ['YYG', 'rCoverType'],
    ['SY', 'uCover'],
    ['XY', 'dCover'],
    ['ZY', 'lCover'],
    ['YY', 'rCover'],
    ['FX', 'crack'],
    ['SJ', 'indent'],
    ['MBLX', 'doorType'],
    ['offset', 'offset'],
    ['PTFS', 'texturePavingStyle'],
    ['CZFX', 'textureAngleDegree'],
    ['CZPY', 'textureOffset'],
    ['CZCC', 'textureSize'],
    ['CBCZFX', 'sectionTextureAngleDegree'],
    ['ST_SFX', 'uCrack'],
    ['ST_XFX', 'dCrack'],
    ['ST_ZFX', 'lCrack'],
    ['ST_YFX', 'rCrack'],
  ].filter((i) => !!i[0]) as Array<[string, string]>
);

/**
 * 将公式中参数转换成实际模型中的参数
 * @param formula
 * @param map
 */
export function formulaTransform(formula: string, map: Map<string, string> = defaultParamMapping): string {
  return formula.replace(/#([a-zA-z$_][a-zA-Z$_\d]*)/g, function ($0, $1, $2) {
    if (map.has($1)) {
      return `#${map.get($1)}`;
    }
    return $0;
  });
}

// 如果ST_SFX参数不存在时，就会自动替换成FX
export const defaultReplaceMap = new Map([
  ['ST_SFX', 'FX'],
  ['ST_XFX', 'FX'],
  ['ST_ZFX', 'FX'],
  ['ST_YFX', 'FX'],
]);

/**
 * 处理模型当中，变量替换逻辑
 */
export function formulaVariableReplace(formula: string, map: Map<string, string> = defaultParamMapping) {
  return (model: CustomModel, replaceMap: Map<string, string> = defaultReplaceMap): string => {
    const replaceFormula = formula.replace(/#([a-zA-z$_][a-zA-Z$_\d]*)/g, function ($0, $1, $2) {
      const alias = map.get($1);
      if (replaceMap.has($1) && !model.hasParam(alias || $1)) {
        return `#${replaceMap.get($1)}`;
      }
      return $0;
    });

    return formulaTransform(replaceFormula, map);
  };
}

/**
 * 针对位置及旋转公式的计算逻辑
 * @param number3
 * @param model
 */
export function formulaNumber3VariableReplace(
  number3: Record<'x' | 'y' | 'z', string | ReturnType<typeof formulaVariableReplace>>,
  model: CustomModel
): Record<'x' | 'y' | 'z', string> {
  const x = typeof number3.x === 'function' ? number3.x(model) : number3.x;
  const y = typeof number3.y === 'function' ? number3.y(model) : number3.y;
  const z = typeof number3.z === 'function' ? number3.z(model) : number3.z;
  return { x, y, z };
}
